#include <rclcpp/rclcpp.hpp>
#include <rclcpp_action/rclcpp_action.hpp>
#include "base_interface_demo01/action/progress.hpp"
using base_interface_demo01::action::Progress;
using namespace std::chrono_literals;
using std::placeholders::_1;
using std::placeholders::_2;
class ProgressActionClientNode: public rclcpp::Node
{
private:
    rclcpp_action::Client<Progress>::SharedPtr client_;
    //std::shared_future<> future;
public:
    ProgressActionClientNode():Node("ProgressActionClientNode")
    {
        RCLCPP_INFO(this->get_logger(),"创建progress_action_client_node_cpp");
        this->client_=rclcpp_action::create_client<Progress>(this,"get_sum");
    }
    void send_goal(int num)
    {
        if(!this->client_->wait_for_action_server(10s))
        {
            RCLCPP_INFO(this->get_logger(),"服务连接失败");
            return;
        }
        Progress::Goal goal=Progress::Goal();
        goal.num=num;
        rclcpp_action::Client<Progress>::SendGoalOptions options;
        options.goal_response_callback=std::bind(&ProgressActionClientNode::goal_resp_feedback,this,_1);

        options.feedback_callback=std::bind(&ProgressActionClientNode::goal_feedback,this,_1,_2);
        options.result_callback=std::bind(&ProgressActionClientNode::goal_result_feedback,this,_1);
        //发送请求
        this->client_->async_send_goal(goal,options);

    }
private:
    void goal_feedback(rclcpp_action::ClientGoalHandle<Progress>::SharedPtr handler,
         Progress::Feedback::ConstSharedPtr feedback)
    {
        //std::shared_ptr<const Progress::Feedback> feedback 等价上面的
        (void)handler;
        int  pro=(int)((feedback->progress)*100);
        RCLCPP_INFO(this->get_logger(), "收到进度反馈: %d%%", pro); 
    }
    void goal_resp_feedback(rclcpp_action::ClientGoalHandle<Progress>::SharedPtr handler)
    {
        // 如果被拒绝会返回空指针 这个action通信第一步
        if(!handler)
        {
            RCLCPP_INFO(this->get_logger(),"目标请求被服务端拒绝");
        }
        else
        {
            RCLCPP_INFO(this->get_logger(),"目标处理中");
        }
    }
    void goal_result_feedback(const rclcpp_action::ClientGoalHandle<Progress>::WrappedResult &result)
    {
        if(result.code==rclcpp_action::ResultCode::SUCCEEDED)
        {
            RCLCPP_INFO(this->get_logger(),"最终结果：%d",result.result->sum);
        }
        else if(result.code==rclcpp_action::ResultCode::ABORTED)
        {
            //程序被强行中断
            RCLCPP_INFO(this->get_logger(),"强行中断");
        }
        else if(result.code==rclcpp_action::ResultCode::CANCELED)
        {
            RCLCPP_INFO(this->get_logger(),"取消");
        }
        else
        {
            RCLCPP_INFO(this->get_logger(),"未知异常");
        }

    }

};       
int main(int argc, char ** argv)
{
    if(argc!=2)
    {
        RCLCPP_ERROR(rclcpp::get_logger("rclcpp"),"请提交一个整形数字");
        return 1;
    }
    int num=atoi(argv[1]);
    rclcpp::init(argc,argv);
    std::shared_ptr<ProgressActionClientNode> client_node=std::make_shared<ProgressActionClientNode>();
    client_node->send_goal(num);
    rclcpp::spin(client_node);
    rclcpp::shutdown();
    return 0;
}